<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>纹理对象，CanvasTexture/VideoTexture</title>
    <style>
      body {
        margin: 0;
        overflow: hidden;
        /* 隐藏body窗口区域滚动条 */
      }
    </style>
    <!--引入three.js三维引擎-->
    <!-- <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script> -->
    <!-- <script src="http://www.yanhuangxueyuan.com/threejs/build/three.js"></script> -->
    <!-- Three.js-master 包示例中的用法 examples/js/controls/OrbitControls.js  版本要匹配-->
    <script src="http://www.yanhuangxueyuan.com/3D/example/three.min.js"></script>
    <script src="../../util/OrbitControls.js"></script>
  </head>
  <body>
    <script type="module">
      import {
        RAFTime,
        sphereMesh,
        cylinderMesh,
        v2ToV3,
      } from "../../util/index.js";

      /**
       * 创建场景对象Scene
       */
      var scene = new THREE.Scene();

      /**
       * 辅助坐标系 参数250表示坐标系大小，可以根据场景大小去设置
       */
      var axisHelper = new THREE.AxisHelper(1000);
      scene.add(axisHelper);

      // CanvasTexture---------------------------------------------------使用canvas作为纹理
      // var canvas = document.createElement("canvas");
      // canvas.width = 512;
      // canvas.height = 128;
      // var c = canvas.getContext("2d");
      // // 矩形区域填充背景
      // c.fillStyle = "#ff00ff";
      // c.fillRect(0, 0, 512, 128);
      // c.beginPath();
      // // 文字
      // c.beginPath();
      // c.translate(256, 64);
      // c.fillStyle = "#000000"; //文本填充颜色
      // c.font = "bold 48px 宋体"; //字体样式设置
      // c.textBaseline = "middle"; //文本与fillText定义的纵坐标
      // c.textAlign = "center"; //文本居中(以fillText定义的横坐标)
      // c.fillText("three.js教程学习", 0, 0);

      // // canvas画布对象作为CanvasTexture的参数重建一个纹理对象
      // // canvas画布可以理解为一张图片
      // var texture = new THREE.CanvasTexture(canvas);
      // //打印纹理对象的image属性
      // // console.log(texture.image);
      // //矩形平面
      // var geometry = new THREE.PlaneGeometry(128, 32);

      // var material = new THREE.MeshPhongMaterial({
      //   map: texture, // 设置纹理贴图
      // });
      // texture.wrapS = THREE.RepeatWrapping;
      // texture.wrapT = THREE.RepeatWrapping;
      // texture.repeat.x = 1;

      // // 创建一个矩形平面网模型，Canvas画布作为矩形网格模型的纹理贴图
      // var mesh = new THREE.Mesh(geometry, material);
      // scene.add(mesh);

      // VideoTexture---------------------------------------------------使用video作为纹理
      // // 创建video对象
      // let video = document.createElement("video");
      // video.src = "../../public/videos/movie.mp4"; // 设置视频地址
      // video.autoplay = "autoplay"; //要设置播放
      // video.loop = true;
      // // video对象作为VideoTexture参数创建纹理对象
      // var texture1 = new THREE.VideoTexture(video);
      // var geometry = new THREE.PlaneGeometry(108, 71); //矩形平面
      // var material = new THREE.MeshPhongMaterial({
      //   map: texture1, // 设置纹理贴图
      // }); //材质对象Material
      // var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
      // scene.add(mesh); //网格模型添加到场景中

      // DataTexture--------------------------------------------------------------------使用data实现每一个像素，作为纹理
      // var geometry = new THREE.PlaneGeometry(128, 128); //矩形平面
      // /**
      //  * 创建纹理对象的像素数据
      //  */
      // var width = 32; //纹理宽度
      // var height = 32; //纹理高度
      // var size = width * height; //像素大小
      // var data = new Uint8Array(size * 3); //size*3：像素在缓冲区占用空间
      // for (let i = 0; i < size * 3; i += 3) {
      //   // 随机设置RGB分量的值
      //   data[i] = 255 * Math.random();
      //   data[i + 1] = 255 * Math.random();
      //   data[i + 2] = 255 * Math.random();
      // }
      // // 创建数据文理对象-----------------------------------------------------RGB格式：THREE.RGBFormat
      // var texture = new THREE.DataTexture(data, width, height, THREE.RGBFormat);
      // texture.needsUpdate = true; //纹理更新
      // //打印纹理对象的image属性
      // // console.log(texture.image);
      // var material = new THREE.MeshPhongMaterial({
      //   map: texture, // 设置纹理贴图
      // }); //材质对象Material
      // var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
      // scene.add(mesh); //网格模型添加到场景中

      var geometry = new THREE.PlaneGeometry(128, 128); //矩形平面
      /**
       * 创建纹理对象的像素数据
       */
      var width = 32; //纹理宽度
      var height = 32; //纹理高度
      var size = width * height; //像素大小
      var data = new Uint8Array(size * 4); //size*4：像素在缓冲区占用空间
      for (let i = 0; i < size * 4; i += 4) {
        // 随机设置RGB分量的值
        data[i] = 255 * Math.random();
        data[i + 1] = 255 * Math.random();
        data[i + 2] = 255 * Math.random();
        // 设置透明度分量A
        data[i + 3] = 255 * 0.5;
      }
      // 创建数据文理对象-----------------------------------------------------RGBA格式：THREE.RGBAFormat
      var texture = new THREE.DataTexture(
        data,
        width,
        height,
        THREE.RGBAFormat
      );
      texture.needsUpdate = true; //纹理更新
      //打印纹理对象的image属性
      console.log(texture.image);

      var material = new THREE.MeshPhongMaterial({
        map: texture, // 设置纹理贴图
        transparent: true, //允许透明设置
        side: THREE.DoubleSide,
      });
      var mesh1 = new THREE.Mesh(geometry, material);
      // var mesh2 = mesh1.clone(); //克隆网格模型
      // mesh2.rotateY(Math.PI);
      scene.add(mesh1); //网格模型添加到场景中
      // scene.add(mesh2);

      // 平行光
      var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
      // 平行光辅助对象
      const directionalLightHelper = new THREE.DirectionalLightHelper(
        directionalLight,
        10
      );
      scene.add(directionalLightHelper);
      // 设置光源位置
      directionalLight.position.set(60, 60, 60);
      scene.add(directionalLight);
      // 设置用于计算阴影的光源对象
      directionalLight.castShadow = true;
      // 设置计算阴影的区域，最好刚好紧密包围在对象周围
      // 计算阴影的区域过大：模糊  过小：看不到或显示不完整
      directionalLight.shadow.camera.near = 0.5;
      directionalLight.shadow.camera.far = 300;
      directionalLight.shadow.camera.left = -100;
      directionalLight.shadow.camera.right = 100;
      directionalLight.shadow.camera.top = 200;
      directionalLight.shadow.camera.bottom = -200;
      // 设置mapSize属性可以使阴影更清晰，不那么模糊
      directionalLight.shadow.mapSize.set(1024, 1024);
      console.log(directionalLight.shadow.camera);

      //环境光
      var ambient = new THREE.AmbientLight(0x000000);
      scene.add(ambient);

      /**
       * 相机设置
       */
      var width = window.innerWidth; //窗口宽度
      var height = window.innerHeight; //窗口高度
      var k = width / height; //窗口宽高比
      var s = 200; //三维场景显示范围控制系数，系数越大，显示的范围越大
      //创建相机对象
      var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 2500);
      camera.position.set(400, 400, 400); //设置相机位置
      camera.lookAt(scene.position); //设置相机方向(指向的场景对象)

      /**
       * 创建渲染器对象
       */
      var renderer = new THREE.WebGLRenderer();
      renderer.setSize(width, height); //设置渲染区域尺寸
      renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
      // 设置渲染器，允许光源阴影渲染
      renderer.shadowMap.enabled = true;
      document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

      // // 监听鼠标、键盘事件，实现 旋转/缩放/平移
      // function render() {
      //   renderer.render(scene, camera); //执行渲染操作
      // }

      // 递归函数,每1/60秒左右,调用一次自己
      const render = RAFTime((t) => {
        renderer.render(scene, camera); //执行渲染操作
        // line.rotateY(0.001 * t);
        // 纹理贴图移动
        // texture.offset.x -= 0.005;
      });

      // 启动渲染---requestAnimationFrame周期性的渲染
      render();

      // 创建，轨迹控件---实现旋转/平移/缩放
      var controls = new THREE.OrbitControls(camera, renderer.domElement);
      // 监听鼠标、键盘事件
      // controls.addEventListener("change");
    </script>
  </body>
</html>
